package com.zhanghu.backendZray.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhanghu.backendZray.cache.ContextCache;
import com.zhanghu.backendZray.enums.MonthEnum;
import com.zhanghu.backendZray.mapper.AccountingMapper;
import com.zhanghu.backendZray.pojo.entity.Accounting;
import com.zhanghu.backendZray.pojo.request.accounting.AccountingQueryRequest;
import com.zhanghu.backendZray.pojo.request.accounting.AccountingRequest;
import com.zhanghu.backendZray.pojo.vo.accounting.AccountingSummaryVo;
import com.zhanghu.backendZray.pojo.vo.accounting.AccountingVo;
import com.zhanghu.backendZray.service.AccountingService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 记账 服务实现类
 * </p>
 *
 * @author zhangdong
 * @since 2024-12-19
 */
@Service
@Slf4j
public class AccountingServiceImpl extends ServiceImpl<AccountingMapper, Accounting> implements AccountingService {


    @Override
    public void saveAccounting(AccountingRequest request) {
        Integer id = request.getId();
        if (id == null) {
            Accounting accounting = new Accounting();
            BeanUtil.copyProperties(request, accounting);
            save(accounting);
            return;
        }
        Accounting accounting = getById(id);
        Assert.isTrue(accounting != null, "此记录不存在");
        BeanUtil.copyProperties(request, accounting);
        updateById(accounting);
    }

    @Override
    public List<AccountingVo> listByYearMonth(AccountingQueryRequest request) {
        request.setUserId(ContextCache.currentUserId());
        return baseMapper.listByYearMonth(request);
    }

    @Override
    public void delete(Integer id) {
        Accounting accounting = getById(id);
        Assert.isTrue(accounting != null, "此记录不存在");
        removeById(id);
    }

    @Override
    public AccountingSummaryVo yearSummary(AccountingQueryRequest request) {
        AccountingSummaryVo vo = new AccountingSummaryVo(new ArrayList<>(12), new ArrayList<>(12));
        Integer accountingYear = request.getAccountingYear();
        LambdaQueryWrapper<Accounting> queryWrapper = new LambdaQueryWrapper<Accounting>().eq(Accounting::getAccountingYear, accountingYear)
                .eq(Accounting::getCreateId, ContextCache.currentUserId());
        List<Accounting> list = list(queryWrapper);
        Map<Byte, List<Accounting>> map = list.stream().collect(Collectors.groupingBy(Accounting::getAccountingMonth));
        MonthEnum[] values = MonthEnum.values();
        for (MonthEnum monthEnum : values) {
            List<Accounting> accountingList = map.get(monthEnum.getValue());
            if (CollUtil.isEmpty(accountingList)) {
                vo.getXSeries().add(monthEnum.getName());
                vo.getYSeries().add(BigDecimal.ZERO);
            } else {
                vo.getXSeries().add(monthEnum.getName());
                vo.getYSeries().add(summaryList(accountingList));
            }
        }
        return vo;
    }

    private BigDecimal summaryList(List<Accounting> list) {
        return list.stream().map(this::summarySingleAccounting).reduce(BigDecimal.ZERO, BigDecimal::add);
    }

    private BigDecimal summarySingleAccounting(Accounting accounting) {
        BigDecimal summary = BigDecimal.ZERO;
        if (accounting.getCatering() != null) {
            summary = summary.add(accounting.getCatering());
        }
        if (accounting.getDailyShopping() != null) {
            summary = summary.add(accounting.getDailyShopping());
        }
        if (accounting.getBabyShopping() != null) {
            summary = summary.add(accounting.getBabyShopping());
        }
        if (accounting.getWaterElectricityGas() != null) {
            summary = summary.add(accounting.getWaterElectricityGas());
        }
        if (accounting.getCar() != null) {
            summary = summary.add(accounting.getCar());
        }
        if (accounting.getPhone() != null) {
            summary = summary.add(accounting.getPhone());
        }
        if (accounting.getTravel() != null) {
            summary = summary.add(accounting.getTravel());
        }
        if (accounting.getHealthcare() != null) {
            summary = summary.add(accounting.getHealthcare());
        }
        if (accounting.getHumanGift() != null) {
            summary = summary.add(accounting.getHumanGift());
        }
        if (accounting.getOthers() != null) {
            summary = summary.add(accounting.getOthers());
        }
        return summary;
    }

    @Override
    public AccountingSummaryVo monthSummary(AccountingQueryRequest request) {
        Integer accountingYear = request.getAccountingYear();
        Byte accountingMonth = request.getAccountingMonth();
        LambdaQueryWrapper<Accounting> queryWrapper = new LambdaQueryWrapper<Accounting>().eq(Accounting::getAccountingYear, accountingYear)
                .eq(Accounting::getAccountingMonth, accountingMonth)
                .eq(Accounting::getCreateId, ContextCache.currentUserId());
        List<Accounting> list = list(queryWrapper);
        return monthSummaryD(list);
    }

    private AccountingSummaryVo monthSummaryD(List<Accounting> list) {
        AccountingSummaryVo vo = new AccountingSummaryVo(new ArrayList<>(12), new ArrayList<>(12));
        vo.getXSeries().add("餐饮");
        vo.getYSeries().add(list.stream().filter(a -> a.getCatering() != null).map(Accounting::getCatering).reduce(BigDecimal.ZERO, BigDecimal::add));
        vo.getXSeries().add("日常购物");
        vo.getYSeries().add(list.stream().filter(a -> a.getDailyShopping() != null).map(Accounting::getDailyShopping).reduce(BigDecimal.ZERO, BigDecimal::add));
        vo.getXSeries().add("宝宝购物");
        vo.getYSeries().add(list.stream().filter(a -> a.getBabyShopping() != null).map(Accounting::getBabyShopping).reduce(BigDecimal.ZERO, BigDecimal::add));
        vo.getXSeries().add("水电煤");
        vo.getYSeries().add(list.stream().filter(a -> a.getWaterElectricityGas() != null).map(Accounting::getWaterElectricityGas).reduce(BigDecimal.ZERO, BigDecimal::add));
        vo.getXSeries().add("车");
        vo.getYSeries().add(list.stream().filter(a -> a.getCar() != null).map(Accounting::getCar).reduce(BigDecimal.ZERO, BigDecimal::add));
        vo.getXSeries().add("手机");
        vo.getYSeries().add(list.stream().filter(a -> a.getPhone() != null).map(Accounting::getPhone).reduce(BigDecimal.ZERO, BigDecimal::add));
        vo.getXSeries().add("出行");
        vo.getYSeries().add(list.stream().filter(a -> a.getTravel() != null).map(Accounting::getTravel).reduce(BigDecimal.ZERO, BigDecimal::add));
        vo.getXSeries().add("医疗");
        vo.getYSeries().add(list.stream().filter(a -> a.getHealthcare() != null).map(Accounting::getHealthcare).reduce(BigDecimal.ZERO, BigDecimal::add));
        vo.getXSeries().add("人情礼物");
        vo.getYSeries().add(list.stream().filter(a -> a.getHumanGift() != null).map(Accounting::getHumanGift).reduce(BigDecimal.ZERO, BigDecimal::add));
        vo.getXSeries().add("其他");
        vo.getYSeries().add(list.stream().filter(a -> a.getOthers() != null).map(Accounting::getOthers).reduce(BigDecimal.ZERO, BigDecimal::add));
        return vo;
    }
}
